/**
 * @Author:Geln Yang
 * @Created:2008-9-30 $ Revision: 1.0 $ $ Author: Geln Yang $ $ Date: 2008-9-30 $
 */
package com.hgy.commonsale.utils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * @Author:Geln Yang
 * @Created:2008-9-30
 */
public class BeanUtil {
	private static final Log logger = LogFactory.getLog(BeanUtil.class);

	public static void copyBeanSimpleProperties(Object dest, Object orig, boolean copyNull) {
		PropertyDescriptor origDescriptors[] = PropertyUtils.getPropertyDescriptors(orig);
		for (int i = 0; i < origDescriptors.length; i++) {
			String name = origDescriptors[i].getName();
			if ("class".equals(name)) {
				continue;
			}
			if (PropertyUtils.isReadable(orig, name) && PropertyUtils.isWriteable(dest, name)) {
				try {
					Object value = PropertyUtils.getSimpleProperty(orig, name);
					if (copyNull || null != value) {
						if (value == null)
							BeanUtils.copyProperty(dest, name, value);
						else {
							Object destValue = PropertyUtils.getSimpleProperty(dest, name);
							if (!value.equals(destValue))
								BeanUtils.copyProperty(dest, name, value);
						}
					}
				} catch (NoSuchMethodException e) {
				} catch (IllegalAccessException e) {
					logger.error(e.getMessage(), e);
				} catch (InvocationTargetException e) {
					logger.error(e.getMessage(), e);
				}
			}
		}
	}

	public static void copyBeanAllSimpleProperties(Object dest, Object orig, boolean copyNull) {
		copyBeanAllSimpleProperties(dest, orig, copyNull, null);
	}

	/**
	 * copy all objects from the original collection into the destination,
	 */
	@SuppressWarnings("unchecked")
	public static <T extends Object> void copyCollection(Collection<T> dest, Collection<T> orig, boolean copyNull) {
		copyCollection(dest, orig, copyNull, null);
	}

	public static <T extends Object> void copyBeanAllSimpleProperties(Object dest, Object orig, boolean copyNull,
			Set<String> unCopyProperties) {
		PropertyDescriptor origDescriptors[] = PropertyUtils.getPropertyDescriptors(orig);
		for (int i = 0; i < origDescriptors.length; i++) {
			String name = origDescriptors[i].getName();
			if ("class".equals(name) || (unCopyProperties != null && unCopyProperties.contains(name)))
				continue;

			if (PropertyUtils.isReadable(orig, name) && PropertyUtils.isWriteable(dest, name)) {
				try {
					Object value = PropertyUtils.getSimpleProperty(orig, name);
					if (copyNull || value != null) {
						BeanUtils.copyProperty(dest, name, value);
					}
				} catch (NoSuchMethodException e) {
				} catch (IllegalAccessException e) {
					logger.error(e.getMessage(), e);
				} catch (InvocationTargetException e) {
					logger.error(e.getMessage(), e);
				}
			}
		}
	}

	@SuppressWarnings("unchecked")
	public static <T extends Object> void copyCollection(Collection<T> dest, Collection<T> orig, boolean copyNull,
			Set<String> unCopyProperties) {
		if (dest == null)
			throw new RuntimeException("Null destination Collection!");
		if (orig == null || orig.size() == 0)
			return;
		Iterator<T> iterator = orig.iterator();
		while (iterator.hasNext()) {
			try {
				Object obj = iterator.next();
				Object item = obj.getClass().newInstance();
				copyBeanAllSimpleProperties(item, obj, copyNull, unCopyProperties);
				dest.add((T) item);
			} catch (InstantiationException e) {
				logger.error(e.getMessage(), e);
			} catch (IllegalAccessException e) {
				logger.error(e.getMessage(), e);
			}
		}
	}
}